package prickworlds.gui;

import static org.lwjgl.opengl.GL11.*;

import org.lwjgl.input.Keyboard;
import org.lwjgl.util.Color;

import prickworlds.structure.KeyEvent;
import prickworlds.structure.MouseEvent;

/**
 * class representing a simple button
 * 
 * @author Faruk Acibal, Richard Dziambor, Christian Holzreuter, Nicolas Winkler
 * 
 */
public class Button extends ActiveControl {

	/**
	 * {@code true} if the cursor is in the area of this Button
	 */
	protected boolean mouseOver;

	/**
	 * {@code true} if the button is in a pressed state
	 */
	protected boolean pressed;

	/**
	 * the caption of the {@link Button}
	 */
	protected String caption;

	/**
	 * mouseover effect
	 */
	protected float enlighted;

	/**
	 * colors defining the background of the button
	 */
	protected static Color topB = new Color(60, 60, 60);
	protected static Color bottomB = new Color(20, 20, 20);

	/**
	 * default constructor
	 */
	public Button() {
		this(0, 0, 0, 0);
	}

	/**
	 * creates a {@link Button} from the specified arguments
	 * 
	 * @param x
	 *            the x-coordinate of the upper left corner of the control
	 * @param y
	 *            the y-coordinate of the upper left corner of the control
	 * @param width
	 *            the width of the control
	 * @param height
	 *            the height of the control
	 */
	public Button(int x, int y, int width, int height) {
		this("", x, y, width, height);
	}

	/**
	 * creates a {@link Button} from the specified arguments
	 * 
	 * @param caption
	 *            the caption of the button
	 * @param x
	 *            the x-coordinate of the upper left corner of the control
	 * @param y
	 *            the y-coordinate of the upper left corner of the control
	 * @param width
	 *            the width of the control
	 * @param height
	 *            the height of the control
	 */
	public Button(String caption, int x, int y, int width, int height) {
		super(x, y, width, height);
		this.caption = caption;
		enlighted = 0.0f;
	}

	/**
	 * @return the Caption of the {@link Button}
	 */
	public String getCaption() {
		return caption;
	}

	/**
	 * sets a new caption
	 * 
	 * @param caption
	 *            the new caption
	 */
	public void setCaption(String caption) {
		this.caption = caption;
	}

	@Override
	public void update() {
		if (mouseOver)
			enlighted = (enlighted * 20.0f + 1.0f) / 21.0f;
		else
			enlighted = (enlighted * 20.0f) / 21.0f;
	}

	/**
	 * displays the {@link Button}
	 */
	@Override
	public void display() {
		if (!visible)
			return;

		Color top = new Color(Button.topB);
		Color bottom = new Color(Button.bottomB);

		if (enlighted > 0.001f) {
			float enlightValue = 50.0f;
			top.set(top.getRed() + (int) (enlighted * enlightValue), top.getBlue()
					+ (int) (enlighted * enlightValue), top.getGreen()
					+ (int) (enlighted * enlightValue));
			bottom.set(bottom.getRed() + (int) (enlighted * enlightValue), bottom
					.getBlue()
					+ (int) (enlighted * enlightValue), bottom.getGreen()
					+ (int) (enlighted * enlightValue));
		}
		if (pressed) {
			Color temp = top;
			top = bottom;
			bottom = temp;
		}

		glColor4f(top.getRed() / 255f, top.getBlue() / 255f,
				top.getGreen() / 255f, top.getAlpha() / 255f);
		glBegin(GL_TRIANGLE_STRIP);

		glVertex2f(x, y);
		glVertex2f(x + width, y);

		glColor4f(bottom.getRed() / 255f, bottom.getBlue() / 255f,
				bottom.getGreen() / 255f, bottom.getAlpha() / 255f);
		
		glVertex2f(x, y + height);
		glVertex2f(x + width, y + height);

		glEnd();

		glColor3f(1.0f, 1.0f, 1.0f);
		Control.font.displayText(x + height * 0.1f, y + height * 0.15f,
				caption, height * 0.8f);
	}

	/**
	 * handles a {@link KeyEvent}
	 */
	@Override
	public void handleKeyEvent(KeyEvent event) {
		if (!visible)
			return;

		if (event.type == KeyEvent.Type.PRESSED) {
			if (event.key == Keyboard.KEY_RETURN) {
				super.performAction();
				event.invalidate();
			}
		}
	}

	/**
	 * handles a {@link MouseEvent}
	 */
	@Override
	public void handleMouseEvent(MouseEvent event) {
		if (!visible)
			return;

		if (event.type == MouseEvent.Type.LEFT_UP && pressed) {
			pressed = false;
			if (event.x > x && event.x < x + width && event.y > y
					&& event.y < y + height) {
				super.performAction();
				event.invalidate();
			}
		} else if (event.type == MouseEvent.Type.LEFT_DOWN) {
			if (event.x > x && event.x < x + width && event.y > y
					&& event.y < y + height) {
				pressed = true;
				event.invalidate();
			}
		} else if (event.type == MouseEvent.Type.MOVE) {
			if (event.x > x && event.x < x + width && event.y > y
					&& event.y < y + height) {
				mouseOver = true;
				event.invalidate();
			} else {
				mouseOver = false;
			}
		}
	}
}
